Initializing Random Choice¶
from random import choices
%matplotlib inline
import numpy as np
import networkx as nx
import pandas as pd
import altair as alt
import nx_altair as nxa
Homework 10: Epidemics in Social Networks¶
1. Analyzing the Epidemic Network¶
p = 0.625 # Calculate the probability for a node to become infected
G = nx.read_weighted_edgelist("contact-high-school-proj-graph.txt")
print(G)
Graph with 327 nodes and 5818 edges
nx.degree(G) # Calculate the degree values for each node in the network
DegreeView({'1': 26, '2': 29, '3': 23, '4': 36, '5': 43, '6': 34, '7': 28, '8': 33, '9': 69, '10': 27, '11': 62, '12': 38, '13': 48, '14': 20, '15': 26, '16': 30, '17': 67, '18': 61, '19': 22, '20': 39, '21': 39, '22': 51, '23': 29, '24': 24, '25': 37, '26': 29, '27': 41, '28': 41, '29': 36, '31': 38, '30': 34, '32': 45, '33': 32, '35': 35, '34': 15, '36': 59, '37': 49, '38': 47, '39': 24, '40': 17, '41': 37, '42': 30, '43': 33, '44': 18, '45': 33, '46': 19, '47': 39, '48': 33, '49': 69, '50': 16, '51': 67, '52': 27, '53': 33, '54': 21, '55': 40, '56': 40, '57': 29, '58': 44, '59': 32, '60': 84, '61': 52, '62': 25, '63': 35, '64': 37, '65': 43, '66': 37, '67': 38, '68': 22, '69': 14, '70': 39, '71': 43, '72': 77, '73': 45, '74': 34, '75': 72, '76': 41, '77': 56, '78': 51, '79': 29, '80': 41, '81': 39, '82': 47, '83': 41, '84': 43, '85': 40, '86': 29, '87': 38, '88': 36, '89': 43, '90': 35, '91': 35, '92': 38, '93': 42, '94': 56, '95': 30, '96': 19, '97': 30, '98': 38, '99': 29, '100': 41, '101': 51, '102': 33, '103': 60, '104': 45, '105': 42, '106': 29, '107': 87, '108': 76, '109': 32, '110': 20, '111': 29, '112': 53, '113': 41, '114': 42, '115': 41, '116': 40, '117': 39, '118': 37, '119': 20, '120': 26, '121': 38, '122': 61, '123': 24, '124': 30, '125': 42, '126': 51, '127': 55, '128': 33, '129': 16, '130': 36, '131': 35, '132': 32, '133': 40, '134': 47, '135': 52, '136': 39, '137': 10, '138': 39, '139': 28, '140': 29, '141': 42, '142': 52, '143': 15, '144': 42, '145': 49, '146': 25, '147': 36, '148': 44, '149': 45, '150': 48, '151': 22, '152': 43, '153': 27, '154': 25, '155': 39, '156': 21, '157': 19, '158': 31, '159': 54, '160': 12, '161': 51, '162': 19, '163': 56, '164': 22, '165': 16, '166': 40, '167': 53, '168': 22, '169': 48, '170': 41, '171': 52, '172': 42, '173': 42, '174': 48, '175': 41, '176': 38, '177': 50, '178': 56, '179': 48, '180': 26, '181': 38, '182': 20, '183': 36, '184': 56, '185': 24, '186': 49, '187': 44, '188': 38, '189': 34, '190': 8, '191': 38, '192': 27, '193': 21, '194': 40, '195': 34, '196': 48, '197': 25, '198': 30, '199': 42, '200': 19, '201': 34, '202': 51, '203': 35, '204': 12, '205': 58, '206': 29, '207': 49, '208': 22, '209': 33, '210': 26, '211': 27, '212': 27, '213': 35, '214': 34, '215': 41, '216': 38, '217': 44, '218': 42, '219': 37, '220': 32, '221': 30, '222': 34, '223': 37, '224': 24, '225': 39, '226': 43, '227': 37, '228': 35, '229': 33, '230': 27, '231': 37, '232': 40, '233': 24, '234': 17, '235': 41, '236': 25, '237': 31, '238': 29, '239': 36, '240': 5, '241': 25, '242': 20, '243': 52, '244': 24, '245': 40, '246': 19, '247': 31, '248': 30, '249': 54, '250': 30, '251': 35, '252': 28, '253': 23, '254': 20, '255': 28, '256': 41, '257': 22, '258': 45, '259': 44, '260': 14, '261': 35, '262': 40, '263': 44, '264': 38, '265': 45, '266': 44, '267': 31, '268': 41, '269': 37, '270': 17, '271': 43, '272': 45, '273': 29, '274': 20, '275': 37, '276': 38, '277': 39, '278': 22, '279': 32, '280': 42, '281': 56, '282': 21, '283': 20, '284': 22, '285': 54, '286': 31, '287': 68, '288': 39, '289': 6, '290': 30, '291': 32, '292': 46, '293': 57, '294': 27, '295': 17, '296': 38, '297': 24, '298': 50, '299': 44, '300': 24, '301': 41, '302': 50, '303': 57, '304': 15, '305': 46, '306': 24, '307': 13, '308': 4, '309': 20, '310': 20, '311': 21, '312': 33, '313': 34, '314': 27, '315': 9, '316': 32, '317': 34, '318': 31, '319': 8, '320': 31, '321': 38, '322': 10, '323': 34, '324': 14, '325': 2, '326': 38, '327': 10})
degree = dict(nx.degree(G)) # Create a dictionary so that the node's attributes doesn't take in the entire list of degree values
nx.set_node_attributes(G, degree, 'degree')
k = sum(degree.values())/ len(degree) # Calculate the average degree
print("Average degree:", k)
Average degree: 35.584097859327215
def r_zero(p,k):
return p*k
r_zero(p,k)
22.24006116207951
Based on this network's average number of contacts per person, also known as degree, the value of $k$ is 35.584097859327215. I calculated this by dividing the sum of all the node’s degree value by the total number of nodes. Based on this network's average number of contacts per person, the value $R_{0}$ is 22.24006116207951. I determined this value by multiplying the probability of a node being infected (0.625) by the average degree value (35.584097859327215). Based on these values, it is very likely that the entire network will be infected.
2. Creating an SIR simulation based on the network's p and k values, using a similar strategy for creating a cascade¶
import copy as copy
import random as random
nx.set_node_attributes(G,"susceptible","status")
names = list(G.nodes)
nx.set_node_attributes(G, dict(zip(G.nodes, names)), "names")
initial_infected_nodes = []
for x in range(0,5):
initial_infected_nodes.append(random.choice(names))
for i in initial_infected_nodes:
G.nodes[i]["status"] = "infected"
pos = nx.spring_layout(G)
alt.data_transformers.disable_max_rows()
viz_1 = nxa.draw_networkx(G,
pos=pos,
node_color="status",
node_tooltip = "names",
cmap='category10'
)
viz_1.interactive()
C:\Users\ericg\anaconda3\Lib\site-packages\altair\utils\core.py:395: FutureWarning: the convert_dtype parameter is deprecated and will be removed in a future version. Do ``ser.astype(object).apply()`` instead if you want ``convert_dtype=False``. col = df[col_name].apply(to_list_if_array, convert_dtype=False) C:\Users\ericg\anaconda3\Lib\site-packages\altair\utils\core.py:395: FutureWarning: the convert_dtype parameter is deprecated and will be removed in a future version. Do ``ser.astype(object).apply()`` instead if you want ``convert_dtype=False``. col = df[col_name].apply(to_list_if_array, convert_dtype=False)
def sir_sim(G):
new_infected_nodes = []
num_infected = 0
for n,d in G.nodes.data():
if d["status"] == "infected":
for i in G.neighbors(n):
if (choices(['infect','nothing'],weights=[p,1-p],k=1)[0]) == 'infect':
new_infected_nodes.append(i) # append the newly infected node
num_infected += 1
d["status"]="recovered" # immediately recover from the virus
# check to see if
for m in range(0,num_infected):
if(n==new_infected_nodes[m]) and d["status"] == "susceptible": # checks to see if the susceptible node is the same as the newly infected node
# AND if the node is not recovered
d["status"]="infected"
plots = []
for n in range(0,10): #run the simulation 10 times
sir_sim(G)
plot = nxa.draw_networkx(G,
pos=pos,
node_color="status",
node_tooltip = "names",
cmap='category10'
)
plots.append(plot)
alt.hconcat(*plots)
C:\Users\ericg\anaconda3\Lib\site-packages\altair\utils\core.py:395: FutureWarning: the convert_dtype parameter is deprecated and will be removed in a future version. Do ``ser.astype(object).apply()`` instead if you want ``convert_dtype=False``. col = df[col_name].apply(to_list_if_array, convert_dtype=False) C:\Users\ericg\anaconda3\Lib\site-packages\altair\utils\core.py:395: FutureWarning: the convert_dtype parameter is deprecated and will be removed in a future version. Do ``ser.astype(object).apply()`` instead if you want ``convert_dtype=False``. col = df[col_name].apply(to_list_if_array, convert_dtype=False) C:\Users\ericg\anaconda3\Lib\site-packages\altair\utils\core.py:395: FutureWarning: the convert_dtype parameter is deprecated and will be removed in a future version. Do ``ser.astype(object).apply()`` instead if you want ``convert_dtype=False``. col = df[col_name].apply(to_list_if_array, convert_dtype=False) C:\Users\ericg\anaconda3\Lib\site-packages\altair\utils\core.py:395: FutureWarning: the convert_dtype parameter is deprecated and will be removed in a future version. Do ``ser.astype(object).apply()`` instead if you want ``convert_dtype=False``. col = df[col_name].apply(to_list_if_array, convert_dtype=False) C:\Users\ericg\anaconda3\Lib\site-packages\altair\utils\core.py:395: FutureWarning: the convert_dtype parameter is deprecated and will be removed in a future version. Do ``ser.astype(object).apply()`` instead if you want ``convert_dtype=False``. col = df[col_name].apply(to_list_if_array, convert_dtype=False) C:\Users\ericg\anaconda3\Lib\site-packages\altair\utils\core.py:395: FutureWarning: the convert_dtype parameter is deprecated and will be removed in a future version. Do ``ser.astype(object).apply()`` instead if you want ``convert_dtype=False``. col = df[col_name].apply(to_list_if_array, convert_dtype=False) C:\Users\ericg\anaconda3\Lib\site-packages\altair\utils\core.py:395: FutureWarning: the convert_dtype parameter is deprecated and will be removed in a future version. Do ``ser.astype(object).apply()`` instead if you want ``convert_dtype=False``. col = df[col_name].apply(to_list_if_array, convert_dtype=False) C:\Users\ericg\anaconda3\Lib\site-packages\altair\utils\core.py:395: FutureWarning: the convert_dtype parameter is deprecated and will be removed in a future version. Do ``ser.astype(object).apply()`` instead if you want ``convert_dtype=False``. col = df[col_name].apply(to_list_if_array, convert_dtype=False) C:\Users\ericg\anaconda3\Lib\site-packages\altair\utils\core.py:395: FutureWarning: the convert_dtype parameter is deprecated and will be removed in a future version. Do ``ser.astype(object).apply()`` instead if you want ``convert_dtype=False``. col = df[col_name].apply(to_list_if_array, convert_dtype=False) C:\Users\ericg\anaconda3\Lib\site-packages\altair\utils\core.py:395: FutureWarning: the convert_dtype parameter is deprecated and will be removed in a future version. Do ``ser.astype(object).apply()`` instead if you want ``convert_dtype=False``. col = df[col_name].apply(to_list_if_array, convert_dtype=False) C:\Users\ericg\anaconda3\Lib\site-packages\altair\utils\core.py:395: FutureWarning: the convert_dtype parameter is deprecated and will be removed in a future version. Do ``ser.astype(object).apply()`` instead if you want ``convert_dtype=False``. col = df[col_name].apply(to_list_if_array, convert_dtype=False) C:\Users\ericg\anaconda3\Lib\site-packages\altair\utils\core.py:395: FutureWarning: the convert_dtype parameter is deprecated and will be removed in a future version. Do ``ser.astype(object).apply()`` instead if you want ``convert_dtype=False``. col = df[col_name].apply(to_list_if_array, convert_dtype=False) C:\Users\ericg\anaconda3\Lib\site-packages\altair\utils\core.py:395: FutureWarning: the convert_dtype parameter is deprecated and will be removed in a future version. Do ``ser.astype(object).apply()`` instead if you want ``convert_dtype=False``. col = df[col_name].apply(to_list_if_array, convert_dtype=False) C:\Users\ericg\anaconda3\Lib\site-packages\altair\utils\core.py:395: FutureWarning: the convert_dtype parameter is deprecated and will be removed in a future version. Do ``ser.astype(object).apply()`` instead if you want ``convert_dtype=False``. col = df[col_name].apply(to_list_if_array, convert_dtype=False) C:\Users\ericg\anaconda3\Lib\site-packages\altair\utils\core.py:395: FutureWarning: the convert_dtype parameter is deprecated and will be removed in a future version. Do ``ser.astype(object).apply()`` instead if you want ``convert_dtype=False``. col = df[col_name].apply(to_list_if_array, convert_dtype=False) C:\Users\ericg\anaconda3\Lib\site-packages\altair\utils\core.py:395: FutureWarning: the convert_dtype parameter is deprecated and will be removed in a future version. Do ``ser.astype(object).apply()`` instead if you want ``convert_dtype=False``. col = df[col_name].apply(to_list_if_array, convert_dtype=False) C:\Users\ericg\anaconda3\Lib\site-packages\altair\utils\core.py:395: FutureWarning: the convert_dtype parameter is deprecated and will be removed in a future version. Do ``ser.astype(object).apply()`` instead if you want ``convert_dtype=False``. col = df[col_name].apply(to_list_if_array, convert_dtype=False) C:\Users\ericg\anaconda3\Lib\site-packages\altair\utils\core.py:395: FutureWarning: the convert_dtype parameter is deprecated and will be removed in a future version. Do ``ser.astype(object).apply()`` instead if you want ``convert_dtype=False``. col = df[col_name].apply(to_list_if_array, convert_dtype=False) C:\Users\ericg\anaconda3\Lib\site-packages\altair\utils\core.py:395: FutureWarning: the convert_dtype parameter is deprecated and will be removed in a future version. Do ``ser.astype(object).apply()`` instead if you want ``convert_dtype=False``. col = df[col_name].apply(to_list_if_array, convert_dtype=False) C:\Users\ericg\anaconda3\Lib\site-packages\altair\utils\core.py:395: FutureWarning: the convert_dtype parameter is deprecated and will be removed in a future version. Do ``ser.astype(object).apply()`` instead if you want ``convert_dtype=False``. col = df[col_name].apply(to_list_if_array, convert_dtype=False)
nx.set_node_attributes(G,"susceptible","status")
names = list(G.nodes)
nx.set_node_attributes(G, dict(zip(G.nodes, names)), "names")
initial_infected_nodes = []
for x in range(0,5):
initial_infected_nodes.append(random.choice(names))
for i in initial_infected_nodes:
G.nodes[i]["status"] = "infected"
statuses = nx.get_node_attributes(G, "status")
status_df = pd.DataFrame({"Step 0": statuses})
for i in range(10): # Rerun the simulation 10 times
sir_sim(G)
new_statuses = nx.get_node_attributes(G,'status')
status_df["Step " + str(i+1)] = list(new_statuses.values()) # Adds a column to the dataframe
status_df
| Step 0 | Step 1 | Step 2 | Step 3 | Step 4 | Step 5 | Step 6 | Step 7 | Step 8 | Step 9 | Step 10 | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible |
| 10 | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible |
| 100 | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible |
| 101 | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible |
| 102 | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 95 | susceptible | infected | recovered | recovered | recovered | recovered | recovered | recovered | recovered | recovered | recovered |
| 96 | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | infected | recovered | recovered | recovered | recovered |
| 97 | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible |
| 98 | susceptible | infected | recovered | recovered | recovered | recovered | recovered | recovered | recovered | recovered | recovered |
| 99 | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible |
327 rows × 11 columns
Based on the data, the infection will stop over time. After each time step, an infected node will recover by the beginning of the next time step and will be unable to infect another node. If this pattern continues, most of the nodes will eventually recover, being unable to reinfect another node, thus ending the infection cycle.
3. Creating a Static Percolation and seeing if it matches with the dynamic visualizations¶
def percolation(G, p, seed=None):
random.seed(seed)
percolated_edges = []
for u,v in G.edges():
if random.choices(['open','blocked'],weights=[p,1-p],k=1)[0] == 'open':
percolated_edges.append((u,v))
return percolated_edges
percolated_edges = percolation(G,p,seed=42)
nx.set_edge_attributes(G, {edge:"open" if edge in percolated_edges else "blocked" for edge in G.edges()}, name="percolation")
pos2 = nx.spring_layout(G, seed=42)
perc_chart = nxa.draw_networkx(G,
pos=pos2,
edge_color = "percolation",
alpha = 0.6,
node_color="red",
edge_tooltip=["percolation"]
)
perc_chart = perc_chart.properties(width=1080,height=720, title="Static Percolation")
perc_chart
C:\Users\ericg\anaconda3\Lib\site-packages\altair\utils\core.py:395: FutureWarning: the convert_dtype parameter is deprecated and will be removed in a future version. Do ``ser.astype(object).apply()`` instead if you want ``convert_dtype=False``. col = df[col_name].apply(to_list_if_array, convert_dtype=False) C:\Users\ericg\anaconda3\Lib\site-packages\altair\utils\core.py:395: FutureWarning: the convert_dtype parameter is deprecated and will be removed in a future version. Do ``ser.astype(object).apply()`` instead if you want ``convert_dtype=False``. col = df[col_name].apply(to_list_if_array, convert_dtype=False)
Based on the static percolation of the SIR epidemic model, I can confirm, that just as the temporal model showed ⅝ of the nodes becoming infected and ⅜ of the nodes being blocked from infection, ⅝ of the edges in the static model are orange (open to infection) and ⅜ of the edges are blue (blocked from infection). The data is exactly the same in both visualizations in different ways. I learned that both visualizations are good representations of the data.
4. Expanding the previous simulation in Part 2 to be a SIRS simulation¶
nx.set_node_attributes(G, 2, "time_steps")
def sirs_sim(G):
new_infected_nodes = []
num_infected = 0
for n,d in G.nodes.data():
if d["status"] == "infected":
for i in G.neighbors(n):
if (choices(['infect','nothing'],weights=[p,1-p],k=1)[0]) == 'infect':
new_infected_nodes.append(i) # append the newly infected node
num_infected += 1
d["status"]="recovered" # immediately recover from the virus
# check to see if the nodes have been infected
for m in range(0,num_infected):
if(n==new_infected_nodes[m]) and d["status"] == "susceptible": # checks to see if the susceptible node is the same as the newly infected node
# AND if the node is not recovered
d["status"]="infected"
if(d["time_steps"])<1 and d["status"] == "recovered": # checks to see if the node is recovered and has had its immunity worn off
d["time_steps"]=2 # resets the time steps
d["status"]="susceptible" # Removes the node's immunity
else:
d["time_steps"] -= 1 # Decreases the number of cycles that a node is immune for by 1
nx.set_node_attributes(G, 2, "time_steps")
nx.set_node_attributes(G,"susceptible","status")
names = list(G.nodes)
nx.set_node_attributes(G, dict(zip(G.nodes, names)), "names")
initial_infected_nodes = []
for x in range(0,5):
initial_infected_nodes.append(random.choice(names))
for i in initial_infected_nodes:
G.nodes[i]["status"] = "infected"
sirs_sim(G)
plots = []
for n in range(0,10): #run the simulation 10 times
sirs_sim(G)
plot = nxa.draw_networkx(G,
pos=pos,
node_color="status",
node_tooltip = "names",
cmap='category10'
)
plots.append(plot)
alt.hconcat(*plots)
C:\Users\ericg\anaconda3\Lib\site-packages\altair\utils\core.py:395: FutureWarning: the convert_dtype parameter is deprecated and will be removed in a future version. Do ``ser.astype(object).apply()`` instead if you want ``convert_dtype=False``. col = df[col_name].apply(to_list_if_array, convert_dtype=False) C:\Users\ericg\anaconda3\Lib\site-packages\altair\utils\core.py:395: FutureWarning: the convert_dtype parameter is deprecated and will be removed in a future version. Do ``ser.astype(object).apply()`` instead if you want ``convert_dtype=False``. col = df[col_name].apply(to_list_if_array, convert_dtype=False) C:\Users\ericg\anaconda3\Lib\site-packages\altair\utils\core.py:395: FutureWarning: the convert_dtype parameter is deprecated and will be removed in a future version. Do ``ser.astype(object).apply()`` instead if you want ``convert_dtype=False``. col = df[col_name].apply(to_list_if_array, convert_dtype=False) C:\Users\ericg\anaconda3\Lib\site-packages\altair\utils\core.py:395: FutureWarning: the convert_dtype parameter is deprecated and will be removed in a future version. Do ``ser.astype(object).apply()`` instead if you want ``convert_dtype=False``. col = df[col_name].apply(to_list_if_array, convert_dtype=False) C:\Users\ericg\anaconda3\Lib\site-packages\altair\utils\core.py:395: FutureWarning: the convert_dtype parameter is deprecated and will be removed in a future version. Do ``ser.astype(object).apply()`` instead if you want ``convert_dtype=False``. col = df[col_name].apply(to_list_if_array, convert_dtype=False) C:\Users\ericg\anaconda3\Lib\site-packages\altair\utils\core.py:395: FutureWarning: the convert_dtype parameter is deprecated and will be removed in a future version. Do ``ser.astype(object).apply()`` instead if you want ``convert_dtype=False``. col = df[col_name].apply(to_list_if_array, convert_dtype=False) C:\Users\ericg\anaconda3\Lib\site-packages\altair\utils\core.py:395: FutureWarning: the convert_dtype parameter is deprecated and will be removed in a future version. Do ``ser.astype(object).apply()`` instead if you want ``convert_dtype=False``. col = df[col_name].apply(to_list_if_array, convert_dtype=False) C:\Users\ericg\anaconda3\Lib\site-packages\altair\utils\core.py:395: FutureWarning: the convert_dtype parameter is deprecated and will be removed in a future version. Do ``ser.astype(object).apply()`` instead if you want ``convert_dtype=False``. col = df[col_name].apply(to_list_if_array, convert_dtype=False) C:\Users\ericg\anaconda3\Lib\site-packages\altair\utils\core.py:395: FutureWarning: the convert_dtype parameter is deprecated and will be removed in a future version. Do ``ser.astype(object).apply()`` instead if you want ``convert_dtype=False``. col = df[col_name].apply(to_list_if_array, convert_dtype=False) C:\Users\ericg\anaconda3\Lib\site-packages\altair\utils\core.py:395: FutureWarning: the convert_dtype parameter is deprecated and will be removed in a future version. Do ``ser.astype(object).apply()`` instead if you want ``convert_dtype=False``. col = df[col_name].apply(to_list_if_array, convert_dtype=False) C:\Users\ericg\anaconda3\Lib\site-packages\altair\utils\core.py:395: FutureWarning: the convert_dtype parameter is deprecated and will be removed in a future version. Do ``ser.astype(object).apply()`` instead if you want ``convert_dtype=False``. col = df[col_name].apply(to_list_if_array, convert_dtype=False) C:\Users\ericg\anaconda3\Lib\site-packages\altair\utils\core.py:395: FutureWarning: the convert_dtype parameter is deprecated and will be removed in a future version. Do ``ser.astype(object).apply()`` instead if you want ``convert_dtype=False``. col = df[col_name].apply(to_list_if_array, convert_dtype=False) C:\Users\ericg\anaconda3\Lib\site-packages\altair\utils\core.py:395: FutureWarning: the convert_dtype parameter is deprecated and will be removed in a future version. Do ``ser.astype(object).apply()`` instead if you want ``convert_dtype=False``. col = df[col_name].apply(to_list_if_array, convert_dtype=False) C:\Users\ericg\anaconda3\Lib\site-packages\altair\utils\core.py:395: FutureWarning: the convert_dtype parameter is deprecated and will be removed in a future version. Do ``ser.astype(object).apply()`` instead if you want ``convert_dtype=False``. col = df[col_name].apply(to_list_if_array, convert_dtype=False) C:\Users\ericg\anaconda3\Lib\site-packages\altair\utils\core.py:395: FutureWarning: the convert_dtype parameter is deprecated and will be removed in a future version. Do ``ser.astype(object).apply()`` instead if you want ``convert_dtype=False``. col = df[col_name].apply(to_list_if_array, convert_dtype=False) C:\Users\ericg\anaconda3\Lib\site-packages\altair\utils\core.py:395: FutureWarning: the convert_dtype parameter is deprecated and will be removed in a future version. Do ``ser.astype(object).apply()`` instead if you want ``convert_dtype=False``. col = df[col_name].apply(to_list_if_array, convert_dtype=False) C:\Users\ericg\anaconda3\Lib\site-packages\altair\utils\core.py:395: FutureWarning: the convert_dtype parameter is deprecated and will be removed in a future version. Do ``ser.astype(object).apply()`` instead if you want ``convert_dtype=False``. col = df[col_name].apply(to_list_if_array, convert_dtype=False) C:\Users\ericg\anaconda3\Lib\site-packages\altair\utils\core.py:395: FutureWarning: the convert_dtype parameter is deprecated and will be removed in a future version. Do ``ser.astype(object).apply()`` instead if you want ``convert_dtype=False``. col = df[col_name].apply(to_list_if_array, convert_dtype=False) C:\Users\ericg\anaconda3\Lib\site-packages\altair\utils\core.py:395: FutureWarning: the convert_dtype parameter is deprecated and will be removed in a future version. Do ``ser.astype(object).apply()`` instead if you want ``convert_dtype=False``. col = df[col_name].apply(to_list_if_array, convert_dtype=False) C:\Users\ericg\anaconda3\Lib\site-packages\altair\utils\core.py:395: FutureWarning: the convert_dtype parameter is deprecated and will be removed in a future version. Do ``ser.astype(object).apply()`` instead if you want ``convert_dtype=False``. col = df[col_name].apply(to_list_if_array, convert_dtype=False)
nx.set_node_attributes(G, 2, "time_steps")
nx.set_node_attributes(G,"susceptible","status")
names = list(G.nodes)
nx.set_node_attributes(G, dict(zip(G.nodes, names)), "names")
initial_infected_nodes = []
for x in range(0,5):
initial_infected_nodes.append(random.choice(names))
for i in initial_infected_nodes:
G.nodes[i]["status"] = "infected"
statuses = nx.get_node_attributes(G, "status")
status_df = pd.DataFrame({"Step 0": statuses})
for i in range(10): # Rerun the simulation 10 times
sirs_sim(G)
new_statuses = nx.get_node_attributes(G,'status')
status_df["Step " + str(i+1)] = list(new_statuses.values()) # Adds a column to the dataframe
status_df
| Step 0 | Step 1 | Step 2 | Step 3 | Step 4 | Step 5 | Step 6 | Step 7 | Step 8 | Step 9 | Step 10 | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible |
| 10 | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible |
| 100 | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible |
| 101 | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible |
| 102 | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 95 | susceptible | infected | recovered | recovered | susceptible | susceptible | infected | recovered | susceptible | infected | recovered |
| 96 | susceptible | susceptible | susceptible | infected | susceptible | susceptible | susceptible | susceptible | infected | susceptible | infected |
| 97 | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible |
| 98 | susceptible | infected | recovered | recovered | susceptible | susceptible | infected | recovered | susceptible | infected | recovered |
| 99 | susceptible | susceptible | susceptible | infected | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible | susceptible |
327 rows × 11 columns
By extending the initial epidemic simulation for the SIRS mode, the speed of infection will increase over time. This is because every recovered node will become susceptible to reinfection after only 2 time steps. In terms of the extent of the epidemic, the entire network will become more likely to be reinfected multiple times as long as the infection exists.